package com.ccp.dev.qbdms.service;

import static com.ccp.dev.qbdms.consts.ZhiLiangConst.API_REPORT_PARA_LIST;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.ccp.dev.core.basic.base.BaseService;
import com.ccp.dev.core.basic.response.ResultData;
import com.ccp.dev.core.basic.response.ReturnCode;
import com.ccp.dev.core.basic.util.ContextUtil;
import com.ccp.dev.core.util.AppUtil;
import com.ccp.dev.core.util.BeanUtils;
import com.ccp.dev.core.util.StringPool;
import com.ccp.dev.core.util.StringUtil;
import com.ccp.dev.extend.model.ExtendSysFile;
import com.ccp.dev.extend.service.ExtendSysOrgService;
import com.ccp.dev.form.service.impl.ScriptImpl;
import com.ccp.dev.qbdms.consts.ZhiLiangConst;
import com.ccp.dev.qbdms.dao.CommonalityDao;
import com.ccp.dev.qbdms.dao.SysReportMasterDao;
import com.ccp.dev.qbdms.dao.SysReportSubDao;
import com.ccp.dev.qbdms.enums.HospitalLevelStateCodeEnum;
import com.ccp.dev.qbdms.enums.PlantLevelStateCodeEnum;
import com.ccp.dev.qbdms.model.BaseBusinessModel;
import com.ccp.dev.qbdms.model.CommonReportModel;
import com.ccp.dev.qbdms.model.Commonality;
import com.ccp.dev.qbdms.model.FlowReportDataWrap;
import com.ccp.dev.qbdms.model.SysOrgDeploy;
import com.ccp.dev.qbdms.model.WQbdFlightJc;
import com.ccp.dev.qbdms.model.WQbdQualityAnalysisReport;
import com.ccp.dev.qbdms.util.BaseUtil;
import com.ccp.dev.qbdms.util.HttpSendUtil;
import com.ccp.dev.qbdms.util.ReadAttachmentUtil;
import com.ccp.dev.qbdms.webservice.cxf.CxfClient;
import com.ccp.dev.system.model.SysOrg;
import com.ccp.dev.system.service.SysOrgService;
import com.ccp.dev.workflow.model.bpm.ProcessCmd;
import com.google.common.collect.Lists;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ReflectionUtils;

@Service
public class CommonalityService extends BaseService<Commonality> {
    Logger log = LoggerFactory.getLogger(this.getClass());

    @Resource
    private CommonalityDao commonalityDao;
    @Resource
    private SysReportSubDao sysReportSubDao;
    @Resource
    private SysReportMasterDao sysReportMasterDao;
    @Resource
    private ScriptImpl scriptImpl;
    @Resource
    private ExtendSysOrgService extendSysOrgService;
    @Resource
    private WQbdQualityAnalysisReportService wQbdQualityAnalysisReportService;
    @Resource
    private SysOrgService sysOrgService;
    @Resource
    private SysOrgDeployService sysOrgDeployService;
    @Resource
    private CommonalityExtendService extendService;
    @Resource
    private CommonalityAsyncService commonalityAsyncService;
    @Resource
    private WQbdFalProblemresetService wQbdFalProblemresetService;
    @Resource
    private AttachmentService attachmentService;

    private static final String REPORT_METHOD = "webReport";

    private static final String UPDATE_STATUS_METHOD = "webUpdateStatus";

    /**
     * 状态位数据上报
     * @param commonality
     * @return 上报数据条数
     */
    @Transactional(rollbackFor = Exception.class)
    public String report(Commonality commonality){
        if(!executable(commonality)){
            return returnMsg(commonality.isRepeatReporting());
        }
        //获取勾选数据主键
        String[] businessIds = commonality.getDataId().split(StringPool.COMMA);
        BaseUtil.SystemLevel level = BaseUtil.getCurrentSystemLevel();
        SysOrgDeploy deploy = sysOrgDeployService.getDeployMethod();
        String className = commonality.getClassName();
        String doingStatus =  level== BaseUtil.SystemLevel.HOSPITALLEVEL?ZhiLiangConst.REPORT_STATUS_REPORTEDTOTHEGROUP:ZhiLiangConst.REPORT_STATUS_TEMP_REPORTTOTHEHOSPITAL;
        // 获取当前登录人单位的code
        String currOrgCode = scriptImpl.getCurrentOrg().getCode();
        try {
            if (BaseUtil.getCurrentSystemLevel()== BaseUtil.SystemLevel.HOSPITALLEVEL) {
                extendService.addLocalStatusDoing(commonality.getDataId(),doingStatus,commonality.getTableName(),currOrgCode);
            }
            else{
                extendService.addLocalStatusDoing(commonality.getDataId(),doingStatus,commonality.getTableName());
            }
            commonalityAsyncService.reportAsyncNoFolw(commonality,deploy,level,scriptImpl.getCurrentOrg());
            return "operation.success";
        } catch (Exception e) {
            log.error("通用上报服务异常 -> 上报失败原因:: {}",e.getMessage());
            return "operation.failure";
        }
    }

    /**
     * 流程处理器方法 用于处理业务数据
     * @param cmd
     */
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public void processHandler(ProcessCmd cmd){
        Map data=cmd.getFormDataMap();
        if(BeanUtils.isNotEmpty(data)){
            String successDataId ;
            String businessId ;
            if(BeanUtils.isNotEmpty(data.get(ZhiLiangConst.SUCCESS_DATA_ID)) && BeanUtils.isNotEmpty(data.get("businessKey"))){
                successDataId = data.get(ZhiLiangConst.SUCCESS_DATA_ID).toString();
                businessId = data.get("businessKey").toString();
                String[] valToArr = successDataId.split(",");
                Map<String,Object> map = new HashMap<>();
                map.put("id",valToArr);
                map.put("businessId",businessId);
                sysReportSubDao.updateReportStatus(map);
            }
            JSONObject obj = JSONObject.fromObject(data);
            Commonality commonality = (Commonality)JSONObject.toBean(obj, Commonality.class);
            cmd.setBusinessKey(commonality.getModelKey());
        }
    }

    /**
     * 流程结束时修改业务表数据状态
     * @param cmd
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateBusinessStatus(ProcessCmd cmd,String className){
        try {
            Map data=cmd.getFormDataMap();
            if(BeanUtils.isNotEmpty(data)){
                String voteAgree = data.get("voteAgree").toString();

                String businessId = data.get("businessKey").toString();
                String tableName = getTableNameByBusinessKey(businessId);
                // 获取当前登录人单位的code
                String currOrgCode = scriptImpl.getCurrentOrg().getCode();
                //判断结束时的按钮是同意还是反对
                if(StringUtils.isNotEmpty(voteAgree) && "1".equals(voteAgree)){
                    String successDataId = "";
                    if(BeanUtils.isNotEmpty(data.get(ZhiLiangConst.SUCCESS_DATA_ID))){
                        successDataId = data.get("successDataId").toString();
                        if(BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.HOSPITALLEVEL){
                            String failId = commonalityDao.queryFailIdByDataAndBusinessId(businessId,successDataId.split(","));
                            //通过数据修改状态为报集团中
                            addAndUpdateES(tableName,successDataId,ZhiLiangConst.REPORT_STATUS_REPORTEDTOTHEGROUP);
                            if(StringUtil.isNotEmpty(failId)){
                                //未通过数据修改状态为报集团失败
                                addAndUpdateES(tableName,failId,ZhiLiangConst.REPORT_STATUS_FAILEDTOSUBMITTOTHEGROUPFORAPPROVAL);
                            }
                            extendService.addLocalStatusDoing(successDataId,ZhiLiangConst.REPORT_STATUS_REPORTEDTOTHEGROUP,tableName,currOrgCode);
                        }
                        else if(BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.PLANTLEVEL){
                            extendService.addLocalStatusDoing(successDataId,ZhiLiangConst.REPORT_STATUS_TEMP_REPORTTOTHEHOSPITAL,tableName);
                        }
                    }
                    else{
                        successDataId = sysReportMasterDao.getAllBusinessIds(businessId);
                        if(BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.HOSPITALLEVEL){
                            //通过数据修改状态为报集团成功
                            addAndUpdateES(tableName,successDataId,ZhiLiangConst.REPORT_STATUS_REPORTEDTOTHEGROUP);
                            extendService.addLocalStatusDoing(successDataId,ZhiLiangConst.REPORT_STATUS_REPORTEDTOTHEGROUP,tableName,currOrgCode);

                        }else if(BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.PLANTLEVEL){
                            extendService.addLocalStatusDoing(successDataId,ZhiLiangConst.REPORT_STATUS_TEMP_REPORTTOTHEHOSPITAL,tableName);
                        }
                    }

                    FlowReportDataWrap frdw = new FlowReportDataWrap();
                    frdw.setDep(sysOrgDeployService.getDeployMethod());
                    frdw.setClassName(className);
                    frdw.setTableName(tableName);
                    frdw.setSuccessDataId(successDataId);
                    frdw.setBusinessId(businessId);
                    frdw.setLevel(BaseUtil.getCurrentSystemLevel());
                    frdw.setSysOrg(scriptImpl.getCurrentOrg());
                    commonalityAsyncService.reportAsyncFolw(frdw);
                }
                else{
                    //根据businessKey获取sys_report_sub表中的业务数据
                    if(BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.HOSPITALLEVEL){
                        String dataId = commonalityDao.queryBusinessIdByDataId(businessId);
                        //通过数据修改状态为报集团成功
                        addAndUpdateES(tableName,dataId,ZhiLiangConst.REPORT_STATUS_FAILEDTOSUBMITTOTHEGROUPFORAPPROVAL);
                        //二级单位驳回后修改全部业务数据状态为报集团审批未通过
                        commonalityDao.updateBusinessStatusHospitalReject(businessId,tableName, ZhiLiangConst.REPORT_STATUS_FAILEDTOSUBMITTOTHEGROUPFORAPPROVAL);
                    }else if(BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.PLANTLEVEL){
                        //三级单位驳回后修改全部业务数据状态为报院审批未通过
                        commonalityDao.updateBusinessStatusPlantReject(businessId,tableName, ZhiLiangConst.REPORT_STATUS_TEMP_FAILEDPASSAPPROVALOFTHEHOSPITAL);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("通用上报服务异常 -> 上报失败原因:: {}",e.getMessage());
        }
    }

    /**
     * 无需上报
     * @param tableName 表名
     * @param ids 业务数据主键
     * @return 返回数据条数
     */
    @Transactional(rollbackFor = Exception.class)
    public String doNotNeedReport(String tableName,String[] ids,String className){
        Map<String,Object> map = new HashMap<>();
        map.put("tableName",tableName);
        map.put("dataId",StringUtils.join(ids,","));
        List<Commonality> businessStatus = commonalityDao.queryBusinessStatusByBusinessIdToHospital(ids,tableName);
        if(BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.GROUPLEVEL){
            try {
                //一级单位操作状态：待确认，已确认，集团退回失败
                for(int i=0;i<ids.length;i++){
                    if(!(ZhiLiangConst.GROUP_TOBECONFIRMED.equals(businessStatus.get(i).getReportStatus()) ||
                            ZhiLiangConst.GROUP_CONFIRMED.equals(businessStatus.get(i).getReportStatus()) ||
                            ZhiLiangConst.GROUP_RETURNFAILED.equals(businessStatus.get(i).getReportStatus()))){
                        return "exist.doNotNeedReport.not.allowed.group";
                    }
                }

                extendService.addLocalStatusDoing(StringUtils.join(ids,","),ZhiLiangConst.GROUP_DONOT_REPORT_ING,tableName);

                for (String id : ids) {
                    BaseBusinessModel resultdata=(BaseBusinessModel)getDataById(className, id);
                    String orgCode=resultdata.getFilldeptHospitalId();
                    int resultcode = sendUpdateStatus(new CommonReportModel(id, ZhiLiangConst.HOSPITAL_DONOT_REPORT, className, tableName, "", orgCode));
                    if (resultcode==RESULT_NONE) {
                        // 集中部署的,不删除,更新状态
                        commonalityDao.doNotNeedReportHospital(tableName,new String[]{id},ZhiLiangConst.HOSPITAL_DONOT_REPORT);
                    }
                    else if(resultcode==RESULT_SUCC){
                        //分级部署的,删除
                        delDataByid(className,id);
                    }
                    else{
                        //分级部署的,且失败了,更新失败状态
                        commonalityDao.doNotNeedReportHospital(tableName,new String[]{id},ZhiLiangConst.GROUP_DONOT_NEED_REPORT_FAILURE);
                    }
                }
                //commonalityDao.doNotNeedReportHospital(tableName,ids,ZhiLiangConst.NOESCALATIONREQUIRED);
                return "operation.success";
            } catch (Exception e) {
                log.error("通用上报服务异常 -> 无需上报:: {}",e.getMessage());
                return "operation.failure";
            }
        }else if(BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.HOSPITALLEVEL){

            try {
                if("W_QBD_QUALITYMANAGE".equals(tableName)){
                    //审核不符合项判断
                    //二级单位允许无需上报的状态:待报集团,院退回失败,报集团审批未通过,集团退回,院内待审核，院内审核不通过，报集团失败,集团退回的无需上报
                    for(int i=0;i<ids.length;i++){
                        if(!(ZhiLiangConst.REPORT_STATUS_GROUPTOBEREPORTED.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.HOSPITAL_FAILEDTORETURN.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.REPORT_STATUS_FAILEDTOSUBMITTOTHEGROUPFORAPPROVAL.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.GROUP_RETURN.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.HOSPITAL_INTERNALAPPROVAL_THEAPPROVALISPENDING.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.HOSPITAL_INTERNALAPPROVAL_APPROVALFAILED.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.REPORT_STATUS_REPORTGROUPFAILURE.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.HOSPITAL_DONOT_REPORT.equals(businessStatus.get(i).getReportStatus())
                        )){
                            return "exist.doNotNeedReport.not.allowed.hospital.audit.non.conformance";
                        }
                    }
                }
                else{
                    //其他判断
                    //二级单位允许无需上报的状态:待报集团,院退回失败,报集团审批未通过,集团退回,报集团失败,无需上报的
                    for(int i=0;i<ids.length;i++){
                        if(!(ZhiLiangConst.REPORT_STATUS_GROUPTOBEREPORTED.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.HOSPITAL_FAILEDTORETURN.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.REPORT_STATUS_FAILEDTOSUBMITTOTHEGROUPFORAPPROVAL.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.GROUP_RETURN.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.REPORT_STATUS_REPORTGROUPFAILURE.equals(businessStatus.get(i).getReportStatus())||
                                ZhiLiangConst.HOSPITAL_DONOT_REPORT.equals(businessStatus.get(i).getReportStatus())
                        )){
                            return "exist.doNotNeedReport.not.allowed.hospital";
                        }
                    }
                }

                extendService.addLocalStatusDoing(StringUtils.join(ids,","),ZhiLiangConst.HOSPITAL_DONOT_REPORT_ING,tableName);

                for (String id : ids) {
                    BaseBusinessModel resultdata=(BaseBusinessModel)getDataById(className, id);
                    String orgCode=resultdata.getFilldeptid();
                    int resultcode = sendUpdateStatus( new CommonReportModel(id,ZhiLiangConst.NOESCALATIONREQUIRED,className,tableName,"",orgCode));
                    if (resultcode==RESULT_NONE) {
                        // 集中部署的,不删除,更新状态
                        commonalityDao.doNotNeedReportHospital(tableName,new String[]{id},ZhiLiangConst.NOESCALATIONREQUIRED);
                    }
                    else if(resultcode==RESULT_SUCC){
                        //分级部署的,删除
                        delDataByid(className,id);
                    }
                    else{
                        //分级部署的,且失败了,更新失败状态
                        commonalityDao.doNotNeedReportHospital(tableName,new String[]{id},ZhiLiangConst.HOSPITAL_DONOT_NEED_REPORT_FAILURE);
                    }
                }
                //commonalityDao.doNotNeedReportPlant(tableName,ids,ZhiLiangConst.NOESCALATIONREQUIRED);

                return "operation.success";
            } catch (Exception e) {
                log.error("通用上报服务异常 -> 无需上报失败原因:: {}",e.getMessage());
                //commonalityDao.doNotNeedReportPlant(tableName,ids,ZhiLiangConst.HOSPITAL_DONOT_NEED_REPORT_FAILURE);
                return "operation.failure";
            }
        }else{
            return "plant.can.not.operation";
        }
    }

    /**
     * 退回待修改
     * @param tableName 表名
     * @param ids 业务数据主键
     * @return 返回数据条数
     */
    @Transactional(rollbackFor = Exception.class)
    public String returnAndUpdate(String tableName,String[] ids,String returnMsg,String className){
        Map<String,Object> map = new HashMap<>();
        map.put("tableName",tableName);
        map.put("dataId",StringUtils.join(ids,","));
        //集团退回
        if(BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.GROUPLEVEL){
            List<Commonality> businessStatus = commonalityDao.queryBusinessStatusByBusinessIdToHospital(ids,tableName);
            try {
                //一级退回状态:集团退回失败,待确认,已确认
                for(int i=0;i<ids.length;i++){
                    if(!(ZhiLiangConst.GROUP_RETURNFAILED.equals(businessStatus.get(i).getReportStatus()) ||
                            ZhiLiangConst.GROUP_TOBECONFIRMED.equals(businessStatus.get(i).getReportStatus()) ||
                            ZhiLiangConst.GROUP_CONFIRMED.equals(businessStatus.get(i).getReportStatus()))){
                        return "exist.updateAndReturn.not.allowed.group";
                    }
                }

                extendService.addLocalStatusDoing(StringUtils.join(ids,","),ZhiLiangConst.GROUP_RETURN_UPDATE_ING,tableName);

                for (String id : ids) {
                    BaseBusinessModel resultdata=(BaseBusinessModel)getDataById(className, id);
                    String orgCode=resultdata.getFilldeptHospitalId();
                    int resultcode = sendUpdateStatus( new CommonReportModel(id,ZhiLiangConst.HOSPITAL_RETURN_UPDATE,className,tableName,returnMsg,orgCode));
                    if (resultcode==RESULT_NONE) {
                        // 集中部署的,不删除,更新状态
                        commonalityDao.returnAndUpdatePlant(tableName,new String[]{id},ZhiLiangConst.HOSPITAL_RETURN_UPDATE,returnMsg);
                    }
                    else if(resultcode==RESULT_SUCC){
                        //分级部署的,修改状态,不能删除数据
                        commonalityDao.returnAndUpdatePlant(tableName,new String[]{id},ZhiLiangConst.GROUP_RETURN_UPDATE,returnMsg);
                    }
                    else{
                        //分级部署的,且失败了,更新失败状态 退回失败
                        commonalityDao.returnAndUpdatePlant(tableName,new String[]{id},ZhiLiangConst.GROUP_RETURN_UPDATE_FAIL,returnMsg);
                    }
                }

                //commonalityDao.returnAndUpdateHospital(tableName,ids,ZhiLiangConst.GROUP_RETURN,returnMsg);
                return "operation.success";
            } catch (Exception e) {
                log.error("通用上报服务异常 -> 退回待修改失败原因:: {}",e.getMessage());
                return "operation.failure";
            }
        }
        else if(BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.HOSPITALLEVEL){
            //院退回
            List<Commonality> businessStatus = commonalityDao.queryBusinessStatusByBusinessIdToHospital(ids,tableName);

            try {
                if("W_QBD_QUALITYMANAGE".equals(tableName)){
                    //审核不符合项判断
                    //二级退回状态: 待报集团,院退回失败,报集团审批未通过,集团退回,院内待审核，院内审核不通过，报集团失败,退回待修改的
                    for(int i=0;i<ids.length;i++){
                        if(!(ZhiLiangConst.REPORT_STATUS_GROUPTOBEREPORTED.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.HOSPITAL_FAILEDTORETURN.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.REPORT_STATUS_FAILEDTOSUBMITTOTHEGROUPFORAPPROVAL.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.GROUP_RETURN.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.HOSPITAL_INTERNALAPPROVAL_THEAPPROVALISPENDING.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.HOSPITAL_INTERNALAPPROVAL_APPROVALFAILED.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.REPORT_STATUS_REPORTGROUPFAILURE.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.HOSPITAL_RETURN_UPDATE.equals(businessStatus.get(i).getReportStatus())
                        )){
                            return "exist.updateAndReturn.not.allowed.hospital.audit.non.conformance";
                        }
                    }
                }
                else{
                    //其他判断
                    //二级退回状态: 待报集团,院退回失败,报集团审批未通过,集团退回，报集团失败
                    for(int i=0;i<ids.length;i++){
                        if(!(ZhiLiangConst.REPORT_STATUS_GROUPTOBEREPORTED.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.HOSPITAL_FAILEDTORETURN.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.REPORT_STATUS_FAILEDTOSUBMITTOTHEGROUPFORAPPROVAL.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.GROUP_RETURN.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.REPORT_STATUS_REPORTGROUPFAILURE.equals(businessStatus.get(i).getReportStatus()) ||
                                ZhiLiangConst.HOSPITAL_RETURN_UPDATE.equals(businessStatus.get(i).getReportStatus())
                        )){
                            return "exist.updateAndReturn.not.allowed.hospital";
                        }
                    }
                }

                extendService.addLocalStatusDoing(StringUtils.join(ids,","),ZhiLiangConst.HOSPITAL_RETURN_UPDATE_ING,tableName);
                for (String id : ids) {
                    BaseBusinessModel resultdata=(BaseBusinessModel)getDataById(className, id);
                    String orgCode=resultdata.getFilldeptid();
                    int resultcode = sendUpdateStatus( new CommonReportModel(id,ZhiLiangConst.PLACE_RETURN_UPDATE,className,tableName,returnMsg,orgCode));
                    if (resultcode==RESULT_NONE) {
                        // 集中部署的,不删除,更新状态
                        commonalityDao.returnAndUpdatePlant(tableName,new String[]{id},ZhiLiangConst.PLACE_RETURN_UPDATE,returnMsg);
                    }
                    else if(resultcode==RESULT_SUCC){
                        //分级部署的,修改状态,不能删除数据
                        commonalityDao.returnAndUpdatePlant(tableName,new String[]{id},ZhiLiangConst.HOSPITAL_RETURN_UPDATE,returnMsg);
                    }
                    else{
                        //分级部署的,且失败了,更新失败状态 退回失败
                        commonalityDao.returnAndUpdatePlant(tableName,new String[]{id},ZhiLiangConst.HOSPITAL_RETURN_UPDATE_FAIL,returnMsg);
                    }
                }

                //commonalityDao.returnAndUpdatePlant(tableName,ids,ZhiLiangConst.PLACE_RETURN_UPDATE,returnMsg);

                return "operation.success";
            } catch (Exception e) {
                log.error("通用上报服务异常 -> 退回待修改失败原因:: {}",e.getMessage());
                return "operation.failure";
            }
        }else{
            return "plant.can.not.operation";
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void addAndUpdateES(String tableName,String businessId, String reportStatus){
        SysOrg sysOrg = extendSysOrgService.getTenOrg(ContextUtil.getCurrentUserId());
        addAndUpdateES(tableName,businessId,reportStatus,sysOrg);
    }

    @Transactional(rollbackFor = Exception.class)
    public void addAndUpdateES(String tableName,String businessId, String reportStatus,SysOrg sysOrg){
        if("W_QBD_QUALITY_ANALYSIS_REPORT".equals(tableName)){
            String[] ids = businessId.split(",");
            for(int i=0;i<ids.length;i++){
                WQbdQualityAnalysisReport wQbdQualityAnalysisReport = wQbdQualityAnalysisReportService.getOneById(ids[i]);
                wQbdQualityAnalysisReport.setId(ids[i]);
                wQbdQualityAnalysisReport.setReportStatus(reportStatus);
                wQbdQualityAnalysisReport.setFilldeptHospital(sysOrg.getOrgName());
                wQbdQualityAnalysisReport.setFilldeptHospitalId(sysOrg.getCode());
                wQbdQualityAnalysisReport.setReportDate(new Date());
                wQbdQualityAnalysisReportService.addAndupdateES(wQbdQualityAnalysisReport);
            }
        }
    }


    /**
     * 根据businessId查询上报流程表中所存表名
     * @param businessKey
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    private String getTableNameByBusinessKey(String businessKey){
        return sysReportMasterDao.getTableNameByBusinessKey(businessKey);
    }

    /**
     * 判断勾选中的数据是否允许上报
     * @param commonality
     * @return 是否允许上报
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean executable(Commonality commonality){
        //获取勾选数据主键
        String[] businessIds = commonality.getDataId().split(",");
        List<Commonality> businessStatus = null;
        //允许重复上报
        if(commonality.isRepeatReporting()){
            if(BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.HOSPITALLEVEL){
                businessStatus = commonalityDao.queryBusinessStatusByBusinessIdToHospital(businessIds,commonality.getTableName());

                //二级单位允许上报的状态:待报集团,报集团审批未通过,集团退回,院退回失败,报集团失败,报集团成功,退回修改的
                // 集中部署的,要判断状态码是否是集团的,如果是集团的则认为是报集团成功的
                for(int i = 0;i<businessStatus.size();i++){
                    String status = businessStatus.get(i).getReportStatus();
                    if(!(ZhiLiangConst.REPORT_STATUS_GROUPTOBEREPORTED.equals(status) ||
                            ZhiLiangConst.REPORT_STATUS_FAILEDTOSUBMITTOTHEGROUPFORAPPROVAL.equals(status) ||
                            ZhiLiangConst.GROUP_RETURN.equals(status) ||
                            ZhiLiangConst.HOSPITAL_FAILEDTORETURN.equals(status) ||
                            ZhiLiangConst.REPORT_STATUS_REPORTGROUPFAILURE.equals(status) ||
                            ZhiLiangConst.REPORT_STATUS_REPORTGROUPSUCCESS.equals(status) ||
                            HospitalLevelStateCodeEnum.BJTCG.getRelatedCode().contains(status) ||
                            ZhiLiangConst.HOSPITAL_RETURN_UPDATE.equals(status) ||
                            ZhiLiangConst.HOSPITAL_RETURN_UPDATE_FAIL.equals(status) ||
                            ZhiLiangConst.HOSPITAL_DONOT_NEED_REPORT_FAILURE.equals(status)
                    )){
                        return false;
                    }
                }
            }else if(BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.PLANTLEVEL){
                businessStatus = commonalityDao.queryBusinessStatusByBusinessIdToPlant(businessIds,commonality.getTableName());
                //三级单位允许上报的状态:待上报,报院失败,报院审批未通过,报院成功,退回待修改
                for(int i = 0;i<businessStatus.size();i++){
                    String status=businessStatus.get(i).getReportStatusTemp();
                    if(!(ZhiLiangConst.REPORT_STATUS_TEMP_TOBEREPORTED.equals(status) ||
                            ZhiLiangConst.REPORT_STATUS_TEMP_REPORTTOTHEHOSPITAL_FAILURE.equals(status) ||
                            ZhiLiangConst.REPORT_STATUS_TEMP_FAILEDPASSAPPROVALOFTHEHOSPITAL.equals(status) ||
                            ZhiLiangConst.REPORT_STATUS_TEMP_REPORTTOTHEHOSPITAL_SUCCESS.equals(status) ||
                            PlantLevelStateCodeEnum.BYCG.getRelatedCode().contains(status) ||
                            ZhiLiangConst.PLACE_RETURN_UPDATE.equals(status))){
                        return false;
                    }
                }
                //修改业务数据信息状态为报院成功
            }else {
                return false;
            }
        }
        else{
            //不允许重复上报
            //二级单位上报
            if(BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.HOSPITALLEVEL){

                businessStatus = commonalityDao.queryBusinessStatusByBusinessIdToHospital(businessIds,commonality.getTableName());
                //判断二级单位状态是否为报集团成功
                //二级单位允许上报的状态:待报集团,报集团审批未通过,院退回失败,报集团失败,退回待修改
                for(int i = 0;i<businessStatus.size();i++){
                    String status = businessStatus.get(i).getReportStatus();
                    //如果有报集团成功的,再次上报了,不允许
                    if (HospitalLevelStateCodeEnum.BJTCG.getRelatedCode().contains(status)) {
                        return false;
                    }
                    if(!(ZhiLiangConst.REPORT_STATUS_GROUPTOBEREPORTED.equals(status) ||
                            ZhiLiangConst.REPORT_STATUS_FAILEDTOSUBMITTOTHEGROUPFORAPPROVAL.equals(status) ||
                            ZhiLiangConst.HOSPITAL_FAILEDTORETURN.equals(status) ||
                            ZhiLiangConst.REPORT_STATUS_REPORTGROUPFAILURE.equals(status) ||
                            ZhiLiangConst.HOSPITAL_RETURN_UPDATE.equals(status) ||
                            ZhiLiangConst.HOSPITAL_RETURN_UPDATE_FAIL.equals(status) ||
                            ZhiLiangConst.HOSPITAL_DONOT_NEED_REPORT_FAILURE.equals(status)
                    )){
                        return false;
                    }
                }
            }else if(BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.PLANTLEVEL){
                businessStatus = commonalityDao.queryBusinessStatusByBusinessIdToPlant(businessIds,commonality.getTableName());
                //三级单位允许上报的状态:待上报,报院失败,报院审批未通过,退回待修改
                for(int i = 0;i<businessStatus.size();i++){
                    // 如果有报集团成功的再次上报,不允许
                    String status = businessStatus.get(i).getReportStatusTemp();
                    if (PlantLevelStateCodeEnum.BYCG.getRelatedCode().contains(status)) {
                        return false;
                    }
                    if(!(ZhiLiangConst.REPORT_STATUS_TEMP_TOBEREPORTED.equals(status) ||
                            ZhiLiangConst.REPORT_STATUS_TEMP_REPORTTOTHEHOSPITAL_FAILURE.equals(status) ||
                            ZhiLiangConst.REPORT_STATUS_TEMP_FAILEDPASSAPPROVALOFTHEHOSPITAL.equals(status) ||
                            ZhiLiangConst.PLACE_RETURN_UPDATE.equals(status))){
                        return false;
                    }
                }
            }else{
                return false;
            }
        }
        return true;
    }


    /**
     * 根据id获取完整数据,上报使用
     * @author
     * @param modelName
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    private Object getDataById(String modelName,String id,String mothodName) {
        modelName = CxfClient.getClassName(modelName);
        Object serviceBean = AppUtil.getBean(modelName+CxfClient.SERVICE);
        Class<? extends Object> cz = serviceBean.getClass();
        Method mh = ReflectionUtils.findMethod(cz,mothodName ,String.class );
        Object result = ReflectionUtils.invokeMethod(mh,serviceBean,id);
        return result;
    }

    /**
     * 根据id获取数据
     * @param modelName
     * @param id
     * @return
     */
    private Object getDataById(String modelName,String id) {
        modelName = CxfClient.getClassName(modelName);
        Object obj = AppUtil.getBean(modelName+CxfClient.SERVICE);
        BaseService baseService = (BaseService)obj;
        Object result = baseService.getOneById(id);
        return result;
    }

    /**
     * 获取多条数据
     * @author zzy
     * @param modelName
     * @param ids
     * @return
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws ClassNotFoundException
     */
    private List<Object> getDataList(String modelName , String ids) {
        String[] businessIds = ids.split(",");
        List<Object> list = new ArrayList<>();
        for (String businessId : businessIds) {
            list.add(getDataById(modelName, businessId,ZhiLiangConst.REPGETONE));
        }
        return list;
    }

    /**
     * 根据id删除数据
     * @param modelName
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    private void delDataByid(String modelName,String id){
        modelName = CxfClient.getClassName(modelName);
        Object obj = AppUtil.getBean(modelName+CxfClient.SERVICE);
        BaseService baseService = (BaseService)obj;
        baseService.delById(id);
    }

    /**
     * 发送数据
     * @author zzy
     * @param deployment
     * @param param
     * @param path
     * @return
     */
    private boolean sendReq(SysOrgDeploy deployment,Map<String,Object> param,String path ){
        String className = path.substring(0, path.length() - ZhiLiangConst.API_URL_REPORT.length());
        if (BeanUtils.isNotEmpty(deployment) && ZhiLiangConst.DEPMETHOND_CLASS.equals(deployment.getDepmethod())) {
            String url = deployment.getUrl()+ZhiLiangConst.URL_API+ZhiLiangConst.URL_VERSION+path;
            if (log.isDebugEnabled()) {
                log.debug("通用上报服务 -> 接口地址: {}",url);
            }
            ResponseEntity<com.alibaba.fastjson.JSONObject> response = HttpSendUtil.httpRestClient(url, HttpMethod.POST, param);
            if (response.getStatusCode() != HttpStatus.OK || (int)response.getBody().get("code")!=ReturnCode.SUCCESS.getCode()) {
                // 接口请求失败,记录日志
                log.error("通用上报服务异常 -> API接口调用失败! 详细:{}",response.toString());
                return false;
            }
        }else if(org.apache.commons.lang3.StringUtils.isNotBlank(className)&&className.equals("wQbdFlightJc")){
            WQbdFlightJcService wQbdFlightJcService = AppUtil.getBean(WQbdFlightJcService.class);
            com.alibaba.fastjson.JSONObject jsonobj = com.alibaba.fastjson.JSONObject.parseObject(
                JSON.toJSONString(param));
            // 获取上报参数,是一个list
            JSONArray listobj = jsonobj.getJSONArray(API_REPORT_PARA_LIST);
            List<WQbdFlightJc> list = listobj.toJavaList(WQbdFlightJc.class);
            boolean hasFile = jsonobj.containsKey(ZhiLiangConst.API_REPORT_PARA_LIST_FILE);
            List<ExtendSysFile> fileList= Lists.newArrayList();
            if (hasFile) {
                JSONArray filelistjson = jsonobj.getJSONArray(ZhiLiangConst.API_REPORT_PARA_LIST_FILE);
                fileList = filelistjson.toJavaList(ExtendSysFile.class);
            }
            wQbdFlightJcService.saveAll(list,fileList);
            return true;
        }
        // 如果没有配置上级单位默认走集中
        return true;
    }

    /**
     * 判断是否走上报接口,返回true表示走接口且成功或者没有配置上级单位
     * @author zzy
     * @param className
     * @param dataId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean sendReportMsg(String className,String dataId,String status,SysOrgDeploy deployment) throws Exception {
        List<Object> list = getDataList(className,dataId);
        for (Object o : list) {
            ((BaseBusinessModel) o).setReportStatus(status);
        }
        Map<String,Object> param = new HashMap<>(3);
        param.put(API_REPORT_PARA_LIST,list);
        try{
            attachmentService.sendAttachments(param,className,deployment);
        }catch (Throwable t){
            throw new Exception(t.getMessage());
        }
        return sendReq(deployment, param, className + ZhiLiangConst.API_URL_REPORT);
    }

    /**没有配置部署方式的返回值*/
    private static final int RESULT_NONE = 0;
    /**调用接口成功*/
    private static final int RESULT_SUCC = 1;
    /**调用接口失败*/
    private static final int RESULT_FAIL = 2;

    /**
     * 退回待修改 无需上报 处理
     * @author zzy
     * @param rrm
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    private int sendUpdateStatus(CommonReportModel rrm){
        SysOrgDeploy deployment = sysOrgDeployService.getDeployMethodByCode(rrm.getOrgCode());
        if (BeanUtils.isEmpty(deployment) || ZhiLiangConst.DEPMETHOND_CENTER.equals(deployment.getDepmethod())) {
            // 集中
            return RESULT_NONE;
        }
        String url = ZhiLiangConst.API_URL_DONOT;
        if (StringUtil.isNotEmpty(rrm.getReturnMsg())) {
            url = ZhiLiangConst.API_URL_RETURNMOTIFY;
        }
        return sendReq(deployment, rrm.toMap(), rrm.getModelName() + url)?RESULT_SUCC:RESULT_FAIL;
    }

    /**
     * 退回待修改更新状态
     * @param tableName
     * @param id
     * @param status
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int returnAndUpdateLocal(String tableName,String id,String status,String returnMsg){
        return commonalityDao.returnAndUpdatePlant(tableName,new String[]{id},status,returnMsg);
    }

    /**
     * 无需上报更新状态
     * @param tableName
     * @param id
     * @param status
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int doNotNeedReportLocal(String tableName,String id,String status){
        return commonalityDao.doNotNeedReportHospital(tableName,new String[]{id},status);
    }

    /**
     * 评定接口
     * @param modelName 模块名称
     * @param model 实体
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean evaluate(String modelName,BaseBusinessModel model) {
        // 是否集中部署
        boolean isCentralizedDeployment = ZhiLiangConst.isCentralizedDeployment(model.getFilldeptid());
        if (!isCentralizedDeployment) {
            String url = ZhiLiangConst.getOrgUrlByCode(model.getFilldeptid());
            url = url +ZhiLiangConst.URL_API + ZhiLiangConst.URL_VERSION + modelName+"/evaluate";
            Map<String, Object> map = new HashMap<>(16);
            map.put("data", model);
            try {
                ResponseEntity<com.alibaba.fastjson.JSONObject> response = HttpSendUtil.httpRestClient(url, HttpMethod.POST, map);
                if (response.getStatusCode() != HttpStatus.OK || (int)response.getBody().get("code")!= ReturnCode.SUCCESS.getCode()) {
                    System.err.println("评定接口调用失败!");
                    return false;
                }
            } catch (Exception e){
                System.err.println("评定接口调用失败!");
                return false;
            }
        }
        return true;
    }

    /**
     * 无流程上报
     *
     * @param modelName 模块名称
     * @param list      实体
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ResultData reportWithNoFlow(String modelName, List list) {
        try {
            // 是否集中部署
            boolean isCentralizedDeployment = ZhiLiangConst.isCentralizedDeployment();
            if (!isCentralizedDeployment) {
                // 分级部署，调用接口发送数据
                // 第一步：获取接收方地址
                SysOrgDeploy sysOrgDeploy = sysOrgDeployService.getDeployMethod();
                String url = sysOrgDeploy.getUrl();
                // 第二步：拼接接口地址
                url = url + ZhiLiangConst.URL_API + ZhiLiangConst.URL_VERSION + modelName + "/report";
                // 第三步：封装参数
                Map<String, Object> map = new HashMap<>(16);
                map.put(ZhiLiangConst.API_REPORT_PARA_LIST, list);
                List<ExtendSysFile> fileList = ReadAttachmentUtil.getReport(map, modelName);
                if (BeanUtils.isNotEmpty(fileList)) {
                    map.put(ZhiLiangConst.API_REPORT_PARA_LIST_FILE, fileList);
                }
                // 第四步：调用接口
                ResponseEntity<com.alibaba.fastjson.JSONObject> response = HttpSendUtil.httpRestClient(url, HttpMethod.POST, map);
                if (response.getStatusCode() != HttpStatus.OK || (Integer)response.getBody().get("code") != ReturnCode.SUCCESS.getCode()) {
                    System.err.println("上报失败，API接口调用失败!!");
                    return new ResultData(1, "上报失败，API接口调用失败!", 0L, null);
                }
            }
        } catch (Exception e) {
            System.err.println("上报失败，API接口调用失败!");
            return new ResultData(1, "上报失败，API接口调用失败!", 0L, null);
        }
        try {
            // 能走到这里说明是集中部署或接口调用成功了,更新本地数据
            Object service = AppUtil.getBean(StringUtil.convertToCamelCase(modelName) + ZhiLiangConst.SERVICE);
            Class<? extends Object> clazz = service.getClass();
            Method m = ReflectionUtils.findMethod(clazz, ZhiLiangConst.UPDATEBATCHBYID, List.class);
            ReflectionUtils.invokeMethod(m, service, list);
        } catch (Exception e){
            System.err.println("上报失败!");
            return new ResultData(1, "上报失败", 0L, null);
        }
        return new ResultData(0, "上报成功", 0L, null);
    }


    /**
     * 督办下发发送接口
     * @param modelName 模块名称
     * @param model 实体
     * @return issueCode 下级单位CODE
     */
    public boolean issue(String modelName,BaseBusinessModel model,String issueCode) {
        // 是否集中部署
        boolean isCentralizedDeployment = ZhiLiangConst.isCentralizedDeployment(issueCode);
        if (!isCentralizedDeployment) {
            // 分级部署，原封不动地下发到下级单位 (下发后数据的变动在接收的 saveAll 中处理)
            String url = ZhiLiangConst.getOrgUrlByCode(issueCode);
            url = url + ZhiLiangConst.URL_API + ZhiLiangConst.URL_VERSION + modelName + "/issue";
            Map<String, Object> map = new HashMap<>(16);
            ArrayList<BaseBusinessModel> baseBusinessModels = new ArrayList<>();
            baseBusinessModels.add(model);
            map.put("data", baseBusinessModels);
            ResponseEntity<com.alibaba.fastjson.JSONObject> response = HttpSendUtil
                .httpRestClient(url, HttpMethod.POST, map);
            if (response.getStatusCode() != HttpStatus.OK
                || (int) response.getBody().get("code") != ReturnCode.SUCCESS.getCode()) {
                System.err.println("下发接口调用失败!");
                return false;
            }
        }
        return true;
    }

    public String returnMsg(Boolean report) {
        //重复上报
        if (report) {
            if (BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.HOSPITALLEVEL) {
                return "exist.reReporting.not.allowed.hospital";
            } else if (BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.PLANTLEVEL) {
                return "exist.reReporting.not.allowed.plant";
            } else {
                return "";
            }
        } else {
            if (BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.HOSPITALLEVEL) {
                return "exist.reporting.not.allowed.hospital";
            } else if (BaseUtil.getCurrentSystemLevel() == BaseUtil.SystemLevel.PLANTLEVEL) {
                return "exist.reporting.not.allowed.plant";
            } else {
                return "";
            }
        }
    }

}
